home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Modules / sybasemodule.c < prev    next >
Text File  |  1995-12-21  |  7KB  |  310 lines

  1. /*
  2. Subject: Re: Sybase module -- input sought 
  3. From: jredford@lehman.com
  4. To: ags@uncompaghre.informatics.jax.org (Alexander G. Smith)
  5. Cc: python-list@cwi.nl
  6. Date: Tue, 10 May 94 11:53:13 -0400
  7.  
  8.  
  9. input sought? how about a complete module? :)
  10.  
  11. This is a fairly incomplete work.. but I have done things dramatically
  12. differently than sybperl would. Given the nature of the language I
  13. find it is easier to simply get ALL results & then muck with the rows
  14. later as parts of the data. This is a subset of the functionality of a
  15. Modula-3 interface to Sybase that I wrote.. I could send you that if
  16. you are interested in a more complete picture.
  17. */
  18.  
  19. #include <stdio.h>
  20.  
  21. #include <sybfront.h>
  22. #include <sybdb.h>
  23.  
  24. #include "allobjects.h"
  25. #include "modsupport.h"
  26.  
  27.  
  28. static object *SybaseError;    /* exception sybase.error */
  29.  
  30.  
  31. typedef struct {
  32.         OB_HEAD
  33.     LOGINREC *login;    /* login record */
  34.     DBPROCESS *dbproc;    /* login record */
  35. } sybdbobject;
  36.  
  37. extern typeobject SybDbtype; /* Forward */
  38.  
  39.  
  40. static sybdbobject *
  41.   newsybdbobject(char *user, char *passwd, char *server)
  42. {
  43.   sybdbobject *s;
  44.  
  45.   s = NEWOBJ(sybdbobject, &SybDbtype);
  46.   if (s != NULL) {
  47.     s->login = dblogin();
  48.     if (user) {
  49.       (void)DBSETLUSER(s->login, user);
  50.     }
  51.     if (passwd) {
  52.       (void)DBSETLPWD(s->login, passwd);
  53.     }
  54.     if(!(s->dbproc = dbopen(s->login, server))) {
  55.       dbloginfree(s->login);
  56.       DEL(s);
  57.       return (NULL);
  58.     }
  59.   }
  60.   return s;
  61. }
  62.  
  63. /* OBJECT FUNCTIONS: sybdb */
  64.  
  65. /* Common code for returning pending results */
  66. static object
  67.   *getresults (DBPROCESS *dbp)
  68. {
  69.   object *results;
  70.   object *list;
  71.   object *tuple;
  72.   object *o;
  73.   int retcode;
  74.   int cols;
  75.   int *fmt;
  76.   int i;
  77.  
  78.   results = newlistobject(0);
  79.   while ((retcode = dbresults(dbp)) != NO_MORE_RESULTS) {
  80.     if (retcode == SUCCEED && DBROWS(dbp) == SUCCEED) {
  81.       list = newlistobject(0);
  82.       cols = dbnumcols(dbp);
  83.       fmt = (int *)malloc(sizeof(int) * cols);
  84.       for (i = 1; i <= cols; i++) {
  85.     switch(dbcoltype(dbp, i)) {
  86.     case SYBCHAR:
  87.       fmt[i-1] = SYBCHAR;
  88.       break;
  89.     case SYBINT1:
  90.       fmt[i-1] = SYBINT1;
  91.       break;
  92.     case SYBINT2:
  93.       fmt[i-1] = SYBINT2;
  94.       break;
  95.     case SYBINT4:
  96.       fmt[i-1] = SYBINT4;
  97.       break;
  98.     case SYBFLT8:
  99.       fmt[i-1] = SYBFLT8;
  100.       break;
  101.     }
  102.       }
  103.       while (dbnextrow(dbp) != NO_MORE_ROWS) {
  104.     tuple = newtupleobject(cols);
  105.     for (i = 1; i <= cols; i++) {
  106.       switch(fmt[i-1]) {
  107.       case SYBCHAR:
  108.         o = newsizedstringobject((char *)dbdata(dbp, i), dbdatlen(dbp, i));
  109.         settupleitem(tuple, i-1, o);
  110.         break;
  111.       case SYBINT1:
  112.         o = newintobject(*((char *)dbdata(dbp, i)));
  113.         settupleitem(tuple, i-1, o);
  114.         break;
  115.       case SYBINT2:
  116.         o = newintobject(*((short *)dbdata(dbp, i)));
  117.         settupleitem(tuple, i-1, o);
  118.         break;
  119.       case SYBINT4:
  120.         o = newintobject(*((int *)dbdata(dbp, i)));
  121.         settupleitem(tuple, i-1, o);
  122.         break;
  123.       case SYBFLT8:
  124.         o = newfloatobject(*((double *)dbdata(dbp, i)));
  125.         settupleitem(tuple, i-1, o);
  126.         break;
  127.       }
  128.     }
  129.     addlistitem(list,tuple);
  130.       }
  131.       free(fmt);
  132.       addlistitem(results,list);
  133.     }
  134.   }
  135.   return (results);
  136. }
  137.  
  138. static object
  139.   *sybdb_sql (self, args)
  140. object *self;
  141. object *args;
  142. {
  143.   char *sql;
  144.   DBPROCESS *dbp;
  145.  
  146.   dbp = ((sybdbobject *)self)->dbproc;
  147.   err_clear ();
  148.   if (!getargs (args, "s", &sql)) {
  149.     return NULL;
  150.   }
  151.   dbcancel(dbp);
  152.   dbcmd(dbp, sql);
  153.   dbsqlexec(dbp);
  154.   return getresults(dbp);
  155. }
  156.  
  157. static object
  158.   *sybdb_sp (self, args)
  159. object *self;
  160. object *args;
  161. {
  162.   char *sp;
  163.   DBPROCESS *dbp;
  164.   object *spargs;
  165.   object *sparg;
  166.   object *results;
  167.   object *r;
  168.   int spargcnt;
  169.   int i;
  170.   int retstatus;
  171.  
  172.   dbp = ((sybdbobject *)self)->dbproc;
  173.   err_clear ();
  174.   if (!getargs (args, "(sO)", &sp, &spargs)) {
  175.     return NULL;
  176.   }
  177.  
  178.   dbcancel(dbp);
  179.   dbrpcinit(dbp, sp, 0);
  180.  
  181.   if (is_tupleobject(spargs)) {
  182.     spargcnt=gettuplesize(spargs);
  183.     for (i=0; i < spargcnt; i++) {
  184.       sparg = gettupleitem(spargs,i);
  185.       if (is_intobject(sparg)) {
  186.     int i;
  187.     i = getintvalue(sparg);
  188.     dbrpcparam(dbp, NULL, 0, SYBINT4, -1, -1, &i);
  189.       } else if (is_floatobject(sparg)) {
  190.     double i;
  191.     i = getfloatvalue(sparg);
  192.     dbrpcparam(dbp, NULL, 0, SYBFLT8, -1, -1, &i);
  193.       } else if (is_stringobject(sparg)) {
  194.     dbrpcparam(dbp, NULL, 0, SYBCHAR, -1, getstringsize(sparg), getstringvalue(sparg));
  195.       } else {
  196.     err_setstr (SybaseError, "Could not handle paramaters to procedure.");
  197.     return NULL;
  198.       }
  199.     }
  200.   } else if (spargs != None) {
  201.     err_setstr (SybaseError, "Could not handle paramaters to procedure.");
  202.     return NULL;
  203.   }
  204.   dbrpcsend(dbp);
  205.   dbsqlok(dbp);
  206.  
  207.   results = getresults(dbp);
  208.   retstatus = dbretstatus(dbp);
  209.  
  210.   r = mkvalue("(iO)", retstatus, results);
  211.   DECREF(results);
  212.   return (r);
  213. }
  214.  
  215.  
  216. static struct methodlist sybdb_methods[] = {
  217.   {"sql",        sybdb_sql},
  218.   {"sp",         sybdb_sp},
  219.   {NULL,         NULL}        /* sentinel */
  220. };
  221.  
  222. static void
  223. sybdb_dealloc(s)
  224.      sybdbobject *s;
  225. {
  226.   dbloginfree(s->login);
  227.   dbclose(s->dbproc);
  228.   DEL(s);
  229. }
  230.  
  231. static object *
  232. sybdb_getattr(s, name)
  233.      sybdbobject *s;
  234.      char *name;
  235. {
  236.   return findmethod(sybdb_methods, (object *) s, name);
  237. }
  238.  
  239.  
  240. typeobject SybDbtype = {
  241.         OB_HEAD_INIT(&Typetype)
  242.         0,
  243.         "sybdb",
  244.         sizeof(sybdbobject),
  245.         0,
  246.         sybdb_dealloc,        /*tp_dealloc*/
  247.         0,            /*tp_print*/
  248.         sybdb_getattr,        /*tp_getattr*/
  249.         0,            /*tp_setattr*/
  250.         0,            /*tp_compare*/
  251.         0,            /*tp_repr*/
  252.         0,            /*tp_as_number*/
  253.         0,            /*tp_as_sequence*/
  254.         0,            /*tp_as_mapping*/
  255. };
  256.  
  257.  
  258.  
  259.  
  260.  
  261. /* MODULE FUNCTIONS: sybase */
  262.  
  263. static object
  264.   *sybase_new (self, args)
  265. object *self;        /* Not used */
  266. object *args;
  267. {
  268.   char *user, *passwd, *server;
  269.   object *db;
  270.  
  271.   err_clear ();
  272.   if (!getargs (args, "(zzz)", &user, &passwd, &server)) {
  273.     return NULL;
  274.   }
  275.   db = (object *) newsybdbobject(user, passwd, server);
  276.   if (!db) {
  277.     /* XXX Should be setting some errstr stuff here based on sybase errors */
  278.     err_setstr (SybaseError, "Could not open connection to server.");
  279.     return NULL;
  280.   }
  281.   return db;
  282. }
  283.  
  284.  
  285. /* List of module functions */
  286. static struct methodlist sybase_methods[]=
  287. {
  288.   {"new", sybase_new},
  289.   {NULL, NULL}            /* sentinel */
  290. };
  291.  
  292. /* Module initialisation */
  293. void initsybase ()
  294. {
  295.   object *m, *d;
  296.  
  297.   /* Create the module and add the functions */
  298.   m = initmodule ("sybase", sybase_methods);
  299.   /* Add some symbolic constants to the module */
  300.   d = getmoduledict (m);
  301.   SybaseError = newstringobject ("sybase.error");
  302.   if (SybaseError == NULL || dictinsert (d, "error", SybaseError) != 0) {
  303.     fatal ("can't define sybase.error");
  304.   }
  305.   /* Check for errors */
  306.   if (err_occurred ()){
  307.     fatal ("can't initialize module sybase");
  308.   }
  309. }
  310.